package com.aop.admin.android_aop_log;

import android.app.Activity;
import android.os.Build;
import android.os.Environment;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.view.View;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @fileName: DAJ
 * @date: 2019/4/11 17:31
 * @auther: YuanShuai
 * @tag: class//DAJ
 * @describe:对啊课堂非侵入式监控过程
 **/
@Aspect
public class DAJ {
    String moncLis = "onClick";
    String monlLis = "onLongClick";
    String lambda = "lambda";

    List<String> errorLog = new ArrayList<>();

    /**
     * @auther YuanShuai
     * @created at 2019/4/15 16:18
     * @desc 标记通知
     */
    @Pointcut("(execution(* *..Activity+.*(..)) ||execution(* *..Layout+.*(..))) && target(Object) && this(Object)||(execution(* *(..)))")
    public void monitoringMethod() throws Throwable {

    }


    /**
     * @auther YuanShuai
     * @created at 2019/4/15 16:18
     * @desc 异常记录
     */
    @RequiresApi(api = Build.VERSION_CODES.N)
    @AfterThrowing(value = "monitoringMethod()", throwing = "ex")
    public void ExceptionThrowing(Throwable ex) throws Throwable {
        FileOutputStream fos = new FileOutputStream(toolUtils.file, true);
        Log.e("DAJ", "(ExceptionThrowing:" + Thread.currentThread().getStackTrace()[2].getLineNumber() + ") --->" +
                " " + toolUtils.file);
        errorLog.add(" ************************************* error **********************************************");
        try {
            for (String s : errorLog) {
                fos.write((s + "\r\n").getBytes());
            }
            fos.write(Log.getStackTraceString(ex).getBytes());
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @auther YuanShuai
     * @created at 2019/4/15 16:18
     * @desc 监控记录
     */
    @Before("monitoringMethod()")
    public void DuiaMethod(JoinPoint joinPoint) throws Throwable {
        if (joinPoint.getSignature().toString().contains("toString()")) return;
        synchronized (this) {
            errorLog.add(" ------------------------------------------------------------------------------------------------------- ");
            Log.e("DAJ", " ------------------------------------------------------------------------------------------------------- ");
            String key = joinPoint.getSignature().toString();
            if (joinPoint.getSignature().getName().contains(moncLis) || joinPoint.getSignature().getName().contains(monlLis)) {
                for (Object o : joinPoint.getArgs()) {
                    if (o != null)
                        if (o instanceof View) {
                            View view = (View) o;
                            Pattern pattern = Pattern.compile(".*\\d+.*");
                            if (pattern.matcher(key).matches()) {
                                key = key.replaceFirst("[\\d]", "[" + view.getResources().getResourceEntryName(view.getId()) + "]");
                            } else {
                                if (key.contains(moncLis)) {
                                    key = new StringBuffer(key).insert((key.lastIndexOf(moncLis) - 1), ".[" + view.getResources().getResourceEntryName(view.getId()) + "]").toString();
                                } else if (key.contains(monlLis)) {
                                    key = new StringBuffer(key).insert((key.lastIndexOf(monlLis) - 1), ".[" + view.getResources().getResourceEntryName(view.getId()) + "]").toString();

                                }
                            }
                        }
                }
            } else if (joinPoint.getSignature().getName().contains(lambda)) {
                for (Object o : joinPoint.getArgs()) {
                    if (o != null)
                        if (o instanceof View) {
                            View view = (View) o;
                            Pattern pattern = Pattern.compile(".*\\d+.*");
                            if (pattern.matcher(key).matches()) {
                                key = key.replaceFirst("[\\d]", "[" + view.getResources().getResourceEntryName(view.getId()) + "]");
                            }
                        }
                }
            }
            Log.e("DAJ", " dRoute = " + key + "    " + joinPoint.getSourceLocation());
            errorLog.add(key + "    " + joinPoint.getSourceLocation());
            for (Object o : joinPoint.getArgs()) {
                if (o != null) {
                    String param = "";
                    if (o instanceof View) {
                        try {
                            param = "[" + ((View) o).getResources().getResourceEntryName(((View) o).getId()) + "]";
                        } catch (Exception e) {
                            param = o.toString();
                        }
                    } else if (o instanceof Activity) {
                        param = ((Activity) o).getPackageName() + ".[" + ((Activity) o).getLocalClassName() + "]";
                    } else {
                        param = o.toString();

                    }
                    Log.e("DAJ", " 参数 -> " + param);
                    errorLog.add(" 参数 -> " + param);
                }
            }

        }
    }

}


